package com.test.p01singleton.example03;

/**
 * 双重检查加锁Double-checked locking
 * 不建议使用：JVA底层模型原因，偶尔会出现问题
 */
public class Singleton03 {

    /**
     * 如果不用volatile，则因为内存模型允许所谓的“无序写入”，可能导致失败。——某个线程可能会获得一个未完全初始化的实例。
     */
    private volatile static Singleton03 instance;


    /**
     * Java 语言规范（Java Language Specification，JLS）要求不能将synchronized 块中的代码移出来。
     * 但是，并没有说不能将synchronized 块外面的代码移入synchronized 块中。JIT 编译器会在这里看到一个优化的机会。
     * 此优化会删除 //4 和 //5 处的代码，导致还是会有无序写入带来的问题
     */
    public static Singleton03 getInstance() {
        if (instance == null) {
            synchronized (Singleton03.class) {        //1
                Singleton03 inst = instance;         //2
                if (inst == null) {
                    synchronized (Singleton03.class) {  //3
                        inst = new Singleton03();      //4
                    }
                    instance = inst;                 //5
                }
            }
        }
        return instance;
    }

}
